﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.IO;

using EnterpriseDT.Net.Ftp;

namespace FreeboxHDVideoPlayer
{
    public class DownloadVideosWorker : AbstractWorker
    {
        public DownloadVideosWorker(string host, int port, string user, string password)
            : base(host, port, user, password)
        {
        }

        private long size;
        private int previousPercentage;
        private long previousSize;
        private DateTime previousDateTime = DateTime.MinValue;

        protected override void OnDoWork(DoWorkEventArgs e)
        {
            Arg arg = e.Argument as Arg;
            using (FreeBoxHDFTP ftp = new FreeBoxHDFTP(this.Host, this.Port, this.User, this.Password))
            {
                ftp.Connect();
                ftp.Login();
                ftp.GotoVideoHome();
                FTPFile[] files = ftp.FTPClient.DirDetails();
                ftp.FTPClient.BytesTransferred += new BytesTransferredHandler(FTPClient_BytesTransferred);
                foreach (FTPFile file in files)
                {
                    if (!file.Dir && arg.Videos.Find(item => item.Name.Equals(file.Name)) != null)
                    {
                        DriveInfo di = DriveInfo.Get(VideoLocalCache.Drive);
                        if (file.Size > di.FreeSpace)
                        {
                            ReportProgress(-1, new DownloadProgress(file.Name, "Disponible à distance (la vidéo ne peut pas être téléchargée car il n'y a pas assez de place sur le disque " + VideoLocalCache.Drive + ")"));
                        }
                        else
                        {
                            size = file.Size;
                            ReportProgress(-1, new DownloadProgress(file.Name, "Démarrage du téléchargement"));
                            ftp.FTPClient.Get(VideoLocalCache.GetLocalPath(file.Name), file.Name);
                            ReportProgress(-1, new DownloadProgress(file.Name, "Disponible en local"));
                        }
                    }
                }
            }
        }

        public void FTPClient_BytesTransferred(object sender, BytesTransferredEventArgs e)
        {
            int percentage = Convert.ToInt32((e.ByteCount * 100) / size);
            if (previousPercentage != percentage)
            {
                if (previousDateTime == DateTime.MinValue)
                {
                    previousDateTime = DateTime.Now;
                }
                previousPercentage = percentage;
                string msg = "Téléchargé à "
                    + percentage
                    + " %";
                TimeSpan ts = new TimeSpan(DateTime.Now.Ticks - previousDateTime.Ticks);
                if (ts.Seconds > 0)
                {
                    long bytesPerSecond = ((e.ByteCount - previousSize) / ts.Seconds);
                    Console.WriteLine(e.RemoteFile + " " + e.ByteCount + " " + ((e.ByteCount - previousSize) / 1024) + " " + ts.Seconds + " " + bytesPerSecond);
                    msg += " (" + BytesFormatter.Format(bytesPerSecond) + "/s)";
                }
                ReportProgress(-1, new DownloadProgress(e.RemoteFile, msg));
                previousDateTime = DateTime.Now;
                previousSize = e.ByteCount;
            }
        }

        public class DownloadProgress
        {
            public DownloadProgress(string fileName, string message)
            {
                FileName = fileName;
                Message = message;
            }

            public string FileName
            {
                get;
                set;
            }

            public string Message
            {
                get;
                set;
            }
        }

        public class Arg
        {
            public Arg(List<Video> videos)
            {
                Videos = videos;
            }

            public List<Video> Videos
            {
                get;
                set;
            }
        }
    }
}
